package com.xmutca.core.plus.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.xmutca.core.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 日志拦截器
 * @author: 彭伟煌(pengweihuang@xmutca.com)
 * @create: 2016-07-09 23:43
 */
@Activate(group = {Constants.PROVIDER}, order = 99999999)
public class ProviderExceptionWrapFilter implements Filter {

    private final static Logger logger = LoggerFactory.getLogger(ProviderExceptionWrapFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        logger.info("ServiceExecute Before: Interface -> {}, method -> {}", invoker.getInterface().getName(), invocation.getMethodName());
        Result result = invoker.invoke(invocation);
        logger.info("ServiceExecute After: Interface -> {}, method -> {}", invoker.getInterface().getName(), invocation.getMethodName());

        if(result.hasException()) {
            Throwable exception = result.getException();

            //业务异常
            if(exception instanceof ServiceException) {
                //异常转换
                ServiceException serviceException = (ServiceException)exception;
                //1. 记录异常
                logger.error("ServiceException: Interface -> {}, method -> {}, status -> {}, message -> {}", invoker.getInterface().getName(), invocation.getMethodName(), serviceException.getStatus(), serviceException.getMessage());
                //2. 包装异常
                return new RpcResult(new com.xmutca.core.common.Result<>(serviceException.getStatus(), serviceException.getMessage()));
            }

            //1. 记录异常
            logger.error("Exception: Interface -> {}, method -> {}, exception: {}, cause: {}", invoker.getInterface().getName(), invocation.getMethodName(), exception.getClass().getName(), exception.getCause());
            //2. 包装异常
            return new RpcResult(new com.xmutca.core.common.Result<>(com.xmutca.core.common.Result.Status.ERROR, "系统发生异常, 容错处理, 请稍后重试~"));
        }
        return result;
    }
}
